﻿//////////////////////////////////////////////////////////////////////////
// resource initializer


//////////////////////////////////////////////////////////////////////////
// static resource

//
template <typename INITTYPE, typename REFTYPE, typename BASETYPE>
struct qbStaticRes
{
	static REFTYPE GetPtr() throw()
	{
		static InternalStaticRes Res;

		return Res.PTR;
	}

private:
	class InternalStaticRes
	{
	public:
		BASETYPE* PTR;

		InternalStaticRes() throw()
		{
			PTR = INITTYPE::CreatePtr();
		}

		~InternalStaticRes() throw()
		{
			//
		}
	};
};

// static rasterizer state
template <
	qgFill fill = QGFILL_SOLID,
	qgCull cull = QGCULL_NONE
>
struct qbStaticRaszState : public qbStaticRes <
	qbStaticRaszState<fill, cull>, qgRaszStateRef, qgRaszState
>
{
	static qgRaszState* CreatePtr() throw()
	{
		qbRaszInitializer inz(fill, cull, 0.0f, 0.0f);
		return qgRdh::Instance->CreateRaszState(inz);
	}
};

// static blend state
template<
	qgColorMask r0mask = QGCM_RGBA,
	qgBlendOp r0cop = QGBLO_ADD,
	qgBlendFactor r0csrc = QGBLF_ONE,
	qgBlendFactor r0cdest = QGBLF_ZERO,
	qgBlendOp r0aop = QGBLO_ADD,
	qgBlendFactor r0asrc = QGBLF_ONE,
	qgBlendFactor r0adest = QGBLF_ZERO,
	//
	qgColorMask r1mask = QGCM_RGBA,
	qgBlendOp r1cop = QGBLO_ADD,
	qgBlendFactor r1csrc = QGBLF_ONE,
	qgBlendFactor r1cdest = QGBLF_ZERO,
	qgBlendOp r1aop = QGBLO_ADD,
	qgBlendFactor r1asrc = QGBLF_ONE,
	qgBlendFactor r1adest = QGBLF_ZERO,
	//
	qgColorMask r2mask = QGCM_RGBA,
	qgBlendOp r2cop = QGBLO_ADD,
	qgBlendFactor r2csrc = QGBLF_ONE,
	qgBlendFactor r2cdest = QGBLF_ZERO,
	qgBlendOp r2aop = QGBLO_ADD,
	qgBlendFactor r2asrc = QGBLF_ONE,
	qgBlendFactor r2adest = QGBLF_ZERO,
	//
	qgColorMask r3mask = QGCM_RGBA,
	qgBlendOp r3cop = QGBLO_ADD,
	qgBlendFactor r3csrc = QGBLF_ONE,
	qgBlendFactor r3cdest = QGBLF_ZERO,
	qgBlendOp r3aop = QGBLO_ADD,
	qgBlendFactor r3asrc = QGBLF_ONE,
	qgBlendFactor r3adest = QGBLF_ZERO
>
struct qbStaticBlndState : public qbStaticRes <
	qbStaticBlndState<
	r0mask, r0cop, r0csrc, r0cdest, r0aop, r0asrc, r0adest,
	r1mask, r1cop, r1csrc, r1cdest, r1aop, r1asrc, r1adest,
	r2mask, r2cop, r2csrc, r2cdest, r2aop, r2asrc, r2adest,
	r3mask, r3cop, r3csrc, r3cdest, r3aop, r3asrc, r3adest
	>, qgBlndStateRef, qgBlndState
>
{
	static qgBlndState* CreatePtr() throw()
	{
		qbBlndInitializer inz(
			r0mask, r0cop, r0csrc, r0cdest, r0aop, r0asrc, r0adest,
			r1mask, r1cop, r1csrc, r1cdest, r1aop, r1asrc, r1adest,
			r2mask, r2cop, r2csrc, r2cdest, r2aop, r2asrc, r2adest,
			r3mask, r3cop, r3csrc, r3cdest, r3aop, r3asrc, r3adest);
		return qgRdh::Instance->CreateBlndState(inz);
	}
};

// static sampler state
template<
	qgFilter filt = QGFLTX_POINT,
	qgAddress addru = QGADR_CLAMP,
	qgAddress addrv = QGADR_CLAMP,
	qgAddress addrw = QGADR_CLAMP,
	kint lbias = 0,
	qgCmpOp cop = QGCOP_NEVER
>
struct qbStaticSplrState : public qbStaticRes <
	qbStaticSplrState<filt, addru, addrv, addrw, lbias, cop>, qgSplrStateRef, qgSplrState
>
{
	static qgSplrState* CreatePtr() throw()
	{
		qbSplrInitializer inz(filt, addru, addrv, addrw, lbias, tpl::ColorValues::Transparent, cop);
		return qgRdh::Instance->CreateSplrState(inz);
	}
};

// static depth stencil state
template<
	bool depth_write = true,
	qgCmpOp depth_func = QGCOP_LEQ,
	bool front_enable = false,
	qgCmpOp front_func = QGCOP_ALWAYS,
	qgStencilOp front_pass = QGSOP_KEEP,
	qgStencilOp front_fail = QGSOP_KEEP,
	qgStencilOp front_depth_fail = QGSOP_KEEP,
	bool back_enable = false,
	qgCmpOp back_func = QGCOP_ALWAYS,
	qgStencilOp back_pass = QGSOP_KEEP,
	qgStencilOp back_fail = QGSOP_KEEP,
	qgStencilOp back_depth_fail = QGSOP_KEEP,
	kbyte mask_read = 0xFF,
	kbyte mask_write = 0xFF
>
struct qbStaticDhslState : public qbStaticRes <
	qbStaticDhslState<
		depth_write, depth_func,
		front_enable, front_func, front_pass, front_fail, front_depth_fail,
		back_enable, back_func, back_pass, back_fail, back_depth_fail,
		mask_read, mask_write
	>, qgDhslStateRef, qgDhslState
>
{
	static qgDhslState* CreatePtr() throw()
	{
		qbDhslInitializer inz(
			depth_write, depth_func,
			front_enable, front_func, front_pass, front_fail, front_depth_fail,
			back_enable, back_func, back_pass, back_fail, back_depth_fail,
			mask_read, mask_write);
		return qgRdh::Instance->CreateDhslState(inz);
	}
};

